package com.glorystone.ins.service.impl;

import com.fastdfs.FastDFSClient;
import com.fastdfs.ResultInfo;
import com.glorystone.ins.dao.AttachmentMapper;
import com.glorystone.ins.domain.Attachment;
import com.glorystone.ins.domain.SysUser;
import com.glorystone.ins.service.AttachmentService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by wangwei on 2018/3/20.
 */
@Slf4j
@Service
public class AttachmentServiceImpl implements AttachmentService {

    @Autowired
    private AttachmentMapper attachmentMapper;
    @Autowired
    private FastDFSClient fastDFSClient;
    @Value("${FASTADDR}")
    private String FASTADDR;

    @Override
    public Attachment findById(Long tid) {
        return attachmentMapper.findById(tid);
    }

    @Override
    public void save(MultipartFile[] files, Integer[] types, String[] alias, Attachment.BusinessTypeEnum businessTypeEnum, Long businessId) {
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();

        try {

            List<Attachment> list = Lists.newArrayListWithCapacity(files.length);

            boolean isAllType = (files.length == types.length);

            for (int i = 0, j = 0; i < files.length; i++) {
                if (files[i] == null || files[i].isEmpty()) {
                    continue;
                }

                ResultInfo result = fastDFSClient.uploadFile(files[i].getBytes(), files[i].getOriginalFilename());
                if (!result.isFlag()) {
                    continue;
                }

                String fastUrl = result.getMsg();
                Attachment attachment = new Attachment();
                attachment.setBusinessType(businessTypeEnum.getValue());
                attachment.setBusinessId(businessId);
                attachment.setName(files[i].getOriginalFilename());

                // 如果“类型”和“文件”数量一致，就取对应下标的类型，不一致默认是相同类型，取第一个
                int type;
                if (isAllType) {
                    type = types[i];
                } else {
                    type = types[0];
                }

                attachment.setType(type);
                attachment.setSortId(i + 1);
                if (type == Attachment.AttachTypeEnum.OTHER.getValue()) {
                    attachment.setAlias(alias[j]);
                    j++;
                }
                attachment.setUrl(fastUrl);
                attachment.setCreateBy(user.getTid());
                list.add(attachment);
            }

            if (CollectionUtils.isNotEmpty(list)) {
                attachmentMapper.saveList(list);
            }

        } catch (IOException e) {
            log.error("<--上传异常-->", e);
        }


    }


    @Override
    public void save(MultipartFile file, Integer type, String alias, Attachment.BusinessTypeEnum businessTypeEnum, Long businessId) {
        if (file != null && !file.isEmpty()) {

            save(new MultipartFile[]{file}, new Integer[]{type}, new String[]{alias}, businessTypeEnum, businessId);

        }

    }


    @Override
    public List<Attachment> queryAttachList(Long businessId, int businessType) {
        List<Attachment> attachmentList = attachmentMapper.findAttechByBusinessId(businessId, businessType);
        return attachmentList.stream().peek(i -> {
            i.setUrl(FASTADDR + i.getUrl());
            Arrays.asList(Attachment.AttachTypeEnum.values()).forEach(j -> {
                if (j.getValue() == i.getType()) {
                    if (j.getValue() == Attachment.AttachTypeEnum.OTHER.getValue()) {
                        i.setTypeName(i.getAlias());
                    } else {
                        i.setTypeName(j.getContent());
                    }
                }

            });

        }).collect(Collectors.toList());

    }

    @Override
    public void update(MultipartFile file, Integer type, String alias, Attachment.BusinessTypeEnum businessTypeEnum, Long businessId) {
        update(new MultipartFile[]{file}, new Integer[]{type}, new String[]{alias}, businessTypeEnum, businessId);

    }

    @Override
    public void update(MultipartFile[] files, Integer[] types, String[] alias, Attachment.BusinessTypeEnum businessTypeEnum, Long businessId) {

        List<MultipartFile> list = Arrays.stream(files).filter(i -> !i.isEmpty()).collect(Collectors.toList());
        if (list.size() == 0) {
            return;
        }
        files = list.toArray(new MultipartFile[]{});

        List<Attachment> attachmentList = queryAttachList(businessId, businessTypeEnum.getValue());
        attachmentList = attachmentList.stream().filter(i -> Arrays.asList(types).contains(i.getType())).collect(Collectors.toList());

        List<Long> waitDeleteIds = attachmentList.stream().map(Attachment::getTid).collect(Collectors.toList());
        List<String> waitDeleteFiles = attachmentList.stream().map(Attachment::getUrl).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(waitDeleteFiles)) {
            attachmentMapper.deleteByIdList(waitDeleteIds);
        }

        waitDeleteFiles.forEach(i -> {
            fastDFSClient.deleteFile(i);
        });


        save(files, types, alias, businessTypeEnum, businessId);

    }

    @Override
    public void delete(Long attachmentId) {
        attachmentMapper.deleteByIdList(Lists.newArrayList(attachmentId));

        Attachment attachment = findById(attachmentId);
        if (attachment != null) {
            fastDFSClient.deleteFile(attachment.getUrl());
        }


    }
}
